﻿namespace HuwmanCode

open System
open HuwmanCode
open NUnit.Framework
open FsUnit

[<TestFixture>]
type ``Fun ``() =
    [<Test>]
    member this.``Fun.Try - fun invokes``() =
        let funInvokes = ref false
        let f() = funInvokes := true
        f |> Fun.Try(fun _ -> ()) |> ignore

        !funInvokes |> should be True

    [<Test>]
    member this.``Fun.Try - compensation invokes when fun raises exn``() =
        let compensationInvokes = ref false
        let f() = failwith "A big bugger up!"
        f |> Fun.Try(fun _ -> compensationInvokes := true) |> ignore

        !compensationInvokes |> should be True

    [<Test>]
    member this.``Fun.Try - returns Some when fun invokes without error``() =
        let f() = ()
        f |> Fun.Try(fun _ -> ()) |> Option.isSome |> should be True

    [<Test>]
    member this.``Fun.Try - returns None when fun raises exn``() =
        let f() = failwith "A big bugger up!"
        f |> Fun.Try(fun _ -> ()) |> Option.isNone |> should be True

    [<Test>]
    member this.``Fun.TryWithRethrow - fun invokes``() =
        let funInvokes = ref false
        let f() = funInvokes := true
        f |> Fun.TryWithRethrow(fun _ -> ()) |> ignore

        !funInvokes |> should be True

    [<Test>]
    member this.``Fun.TryWithRethrow - compensation invokes when fun raises exn``() =
        let compensationInvokes = ref false
        let f() = failwith "A big bugger up!"

        try
            f |> Fun.TryWithRethrow(fun e -> compensationInvokes := true) |> ignore
        with _ -> ()

        !compensationInvokes |> should be True

    [<Test>]
    member this.``Fun.TryWithRethrow - exn is reraised when fun raises exn``() =
        let exceptionIsReraised = ref false
        let f() = failwith "A big bugger up!"
        
        try
            f |> Fun.TryWithRethrow(fun _ -> ()) |> ignore
        with _ -> exceptionIsReraised := true

        !exceptionIsReraised |> should be True